#include "channel.hpp"
/**
 * @file connection.hpp
 * @brief 消息队列连接管理模块
 * 
 * 本模块实现连接的建立、维护、销毁及信道管理功能。
 * 包含两个核心组件：
 * 1. Connection - 封装单个TCP连接的通信上下文
 * 2. ConnectionManager - 管理所有活跃连接的生命周期
 */
namespace bitmq 
{
    /// @class Connection
    /// @brief 封装单个客户端连接的通信上下文
    ///
    /// 负责管理连接级别的资源：
    /// - 维护底层TCP连接
    /// - 管理多个信道(Channel)的生命周期
    /// - 处理连接级别的协议编解码
    class Connection 
    {
        public:
            using ptr = std::shared_ptr<Connection>;
            
            /// @brief 构造函数
            /// @param host 所属虚拟主机
            /// @param cmp 消费者管理器
            /// @param codec 协议编解码器
            /// @param conn 底层TCP连接
            /// @param pool 关联的线程池
            Connection(const VirtualHost::ptr &host, 
                const ConsumerManager::ptr &cmp, 
                const ProtobufCodecPtr &codec, 
                const muduo::net::TcpConnectionPtr &conn,
                const threadpool::ptr &pool) :
                _conn(conn),
                _codec(codec),
                _cmp(cmp),
                _host(host),
                _pool(pool),
                _channels(std::make_shared<ChannelManager>()){}
            
            /// @brief 打开新信道
            /// @param req 打开信道请求对象
            /// @note 若信道ID重复则操作失败
            void openChannel(const openChannelRequestPtr &req) 
            {
                //1. 判断信道ID是否重复,创建信道
                bool ret = _channels->openChannel(req->cid(), _host, _cmp, _codec, _conn, _pool);
                if (ret == false) 
                {
                    DLOG("创建信道的时候，信道ID重复了");
                    return basicResponse(false, req->rid(), req->cid());
                }
                DLOG("%s 信道创建成功！", req->cid().c_str());
                //3. 给客户端进行回复
                return basicResponse(true, req->rid(), req->cid());
            }
            
            /// @brief 关闭指定信道
            /// @param req 关闭信道请求对象
            void closeChannel(const closeChannelRequestPtr &req) 
            {
                _channels->closeChannel(req->cid());
                return basicResponse(true, req->rid(), req->cid());
            }
            
            /// @brief 获取指定信道
            /// @param cid 信道ID
            /// @return 信道智能指针，若不存在返回空指针
            Channel::ptr getChannel(const std::string &cid) 
            {
                return _channels->getChannel(cid);
            }
        private:
            /// @brief 发送基础响应
            /// @param ok 操作是否成功
            /// @param rid 请求ID
            /// @param cid 信道ID
            void basicResponse(bool ok, const std::string &rid, const std::string &cid) {
                basicCommonResponse resp;
                resp.set_rid(rid);
                resp.set_cid(cid);
                resp.set_ok(ok);
                _codec->send(_conn, resp);
            }
        private:
            muduo::net::TcpConnectionPtr _conn;          ///< 底层TCP连接
            ProtobufCodecPtr _codec;                     ///< 协议编解码器
            ConsumerManager::ptr _cmp;                   ///< 消费者管理器
            VirtualHost::ptr _host;                      ///< 所属虚拟主机
            threadpool::ptr _pool;                       ///< 关联线程池
            ChannelManager::ptr _channels;               ///< 信道管理器
    };

    /// @class ConnectionManager
    /// @brief 管理所有活跃连接的生命周期
    ///
    /// 提供线程安全的连接管理功能：
    /// - 创建新连接
    /// - 销毁断开连接
    /// - 快速查找连接
    class ConnectionManager 
    {
        public:
            using ptr = std::shared_ptr<ConnectionManager>;
            ConnectionManager() {}
            
            /// @brief 创建新连接
            /// @param host 虚拟主机
            /// @param cmp 消费者管理器
            /// @param codec 协议编解码器
            /// @param conn 底层TCP连接
            /// @param pool 线程池
            /// @note 若连接已存在则忽略
            void newConnection(const VirtualHost::ptr &host, 
                const ConsumerManager::ptr &cmp, 
                const ProtobufCodecPtr &codec, 
                const muduo::net::TcpConnectionPtr &conn,
                const threadpool::ptr &pool) {
                std::unique_lock<std::mutex> lock(_mutex);
                auto it = _conns.find(conn);
                if (it != _conns.end()) 
                {
                    return ;
                }
                Connection::ptr self_conn = std::make_shared<Connection>(host, cmp, codec, conn, pool);
                _conns.insert(std::make_pair(conn, self_conn));
            }
            
            /// @brief 删除指定连接
            /// @param conn 要删除的TCP连接
            void delConnection(const muduo::net::TcpConnectionPtr &conn) 
            {
                std::unique_lock<std::mutex> lock(_mutex);
                _conns.erase(conn);
            }
            
            /// @brief 获取连接对象
            /// @param conn 底层TCP连接
            /// @return 连接智能指针，若不存在返回空指针
            Connection::ptr getConnection(const muduo::net::TcpConnectionPtr &conn) 
            {
                std::unique_lock<std::mutex> lock(_mutex);
                auto it = _conns.find(conn);
                if (it == _conns.end()) 
                {
                    return Connection::ptr();
                }
                return it->second;
            }
        private:
            std::mutex _mutex;  ///< 连接映射表的互斥锁
            std::unordered_map<muduo::net::TcpConnectionPtr, Connection::ptr> _conns;  ///< 连接映射表
    };
}